home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqdisplay / cache.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-15  |  9.0 KB  |  227 lines

  1. #define    LIBQDISPLAY_CORE
  2. #include "../include/libqdisplay.h"
  3.  
  4. struct texture **cachedFaces;
  5.  
  6. void InitFaceCache(__memBase)
  7. {
  8.   if (!(cachedFaces = (struct texture **)kmalloc(bspMem->shared.quake1.numfaces * sizeof(struct texture *))))
  9.     Error(failed_memory, bspMem->shared.quake1.numfaces * sizeof(struct texture *), "face-cache");
  10. }
  11.  
  12. static void GetMipMaps(__memBase, struct texture *Text, int TMipMap)
  13. {
  14.   struct dmiptexlump_t *mtl = (struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata;
  15.   struct mipmap *mip = (struct mipmap *)(bspMem->shared.quake1.dtexdata + mtl->dataofs[TMipMap]);
  16.   short int i;
  17.  
  18.   if (mip->name[0] == WARP_MIPMAP) {
  19.     switch (mip->name[1]) {
  20.       case 'w':    Text->textureType = WATER_TYPE;       break;        /* *w(ater)... */
  21.       case 's':    Text->textureType = SLIME_TYPE;       break;        /* *s(lime)... */
  22.       case 'l':    Text->textureType = LAVA_TYPE;       break;        /* *l(ava)... */
  23.       case 't':    Text->textureType = TELEPORT_TYPE; break;        /* *t(eleport)... */
  24.       default:    Text->textureType = OTHER_TYPE;       break;        /* *... */
  25.     }
  26.     Text->mipMaps[MIPMAP_0].rawBody.width = WARP_X;
  27.     Text->mipMaps[MIPMAP_0].rawBody.height = WARP_Y;
  28.     Text->mipMaps[MIPMAP_0].rawBody.size = WARP_X * WARP_Y;
  29.     Text->mipMaps[MIPMAP_0].newBody.width = WARP_X;
  30.     Text->mipMaps[MIPMAP_0].newBody.height = WARP_Y;
  31.     Text->mipMaps[MIPMAP_0].newBody.size = WARP_X * WARP_Y;
  32.     Text->textGradient.u = 0;
  33.     Text->textGradient.v = 0;
  34.   }
  35.   else if (!__strncmp(mip->name, SKY_MIPMAP, 3)) {
  36.     Text->textureType = SKY_TYPE;
  37.     Text->mipMaps[MIPMAP_0].rawBody.width = SKY_X;
  38.     Text->mipMaps[MIPMAP_0].rawBody.height = SKY_Y;
  39.     Text->mipMaps[MIPMAP_0].rawBody.size = SKY_X * SKY_Y;
  40.     Text->mipMaps[MIPMAP_0].newBody.width = SKY_X;
  41.     Text->mipMaps[MIPMAP_0].newBody.height = SKY_Y;
  42.     Text->mipMaps[MIPMAP_0].newBody.size = SKY_X * SKY_Y;
  43.     Text->textGradient.u = 0;
  44.     Text->textGradient.v = 0;
  45.   }
  46.   else {
  47.     if (mip->name[0] == ANIM_MIPMAP)
  48.       Text->textureType = ANIM_TYPE;
  49.     else
  50.       Text->textureType = WALL_TYPE;
  51.  
  52.     Text->mipMaps[MIPMAP_0].rawBody.width = LittleLong(mip->width);
  53.     Text->mipMaps[MIPMAP_0].rawBody.height = LittleLong(mip->height);
  54.     Text->mipMaps[MIPMAP_0].rawBody.size = Text->mipMaps[MIPMAP_0].rawBody.width * Text->mipMaps[MIPMAP_0].rawBody.height;
  55.     Text->mipMaps[MIPMAP_0].newBody.width = Text->faceExtent.u10;
  56.     Text->mipMaps[MIPMAP_0].newBody.height = Text->faceExtent.v10;
  57.     Text->mipMaps[MIPMAP_0].newBody.size = Text->mipMaps[MIPMAP_0].newBody.width * Text->mipMaps[MIPMAP_0].newBody.height;
  58.     Text->textGradient.u = Text->faceExtent.u0;
  59.     Text->textGradient.v = Text->faceExtent.v0;
  60.   }
  61.   Text->mipMaps[MIPMAP_0].rawBody.data = (unsigned char *)mip + LittleLong(mip->offsets[MIPMAP_0]);
  62.   Text->mipMaps[MIPMAP_0].step = 16;
  63.   Text->mipMaps[MIPMAP_0].shift = 4;
  64.   Text->mipMaps[MIPMAP_0].row = Text->mipMaps[MIPMAP_0].newBody.width - Text->mipMaps[MIPMAP_0].step;
  65.   if ((Text->mipMaps[MIPMAP_0].y = Text->faceExtent.v0 % Text->mipMaps[MIPMAP_0].rawBody.height) < 0)
  66.     Text->mipMaps[MIPMAP_0].y += Text->mipMaps[MIPMAP_0].rawBody.height;
  67.   if ((Text->mipMaps[MIPMAP_0].x0 = Text->faceExtent.u0 % Text->mipMaps[MIPMAP_0].rawBody.width) < 0)
  68.     Text->mipMaps[MIPMAP_0].x0 += Text->mipMaps[MIPMAP_0].rawBody.width;
  69.   Text->mipMaps[MIPMAP_0].rescale = scalw((double)(8), -3);    /* / 8.0; */
  70.  
  71.   for (i = MIPMAP_1; i < MIPMAP_MAX; i++) {            /* an enum cycles, produces no overflow */
  72.     Text->mipMaps[i].rawBody.data = (unsigned char *)mip + LittleLong(mip->offsets[i]);
  73.     Text->mipMaps[i].rawBody.width = Text->mipMaps[MIPMAP_0].rawBody.width >> i;
  74.     Text->mipMaps[i].rawBody.height = Text->mipMaps[MIPMAP_0].rawBody.height >> i;
  75.     Text->mipMaps[i].rawBody.size = Text->mipMaps[MIPMAP_0].rawBody.size >> i >> i;
  76.     Text->mipMaps[i].newBody.width = Text->mipMaps[MIPMAP_0].newBody.width >> i;
  77.     Text->mipMaps[i].newBody.height = Text->mipMaps[MIPMAP_0].newBody.height >> i;
  78.     Text->mipMaps[i].newBody.size = Text->mipMaps[MIPMAP_0].newBody.size >> i >> i;
  79.     Text->mipMaps[i].step = 16 >> i;
  80.     Text->mipMaps[i].shift = 4 - i;
  81.     Text->mipMaps[i].row = Text->mipMaps[i].newBody.width - Text->mipMaps[i].step;
  82.     Text->mipMaps[i].rescale = scalw(Text->mipMaps[MIPMAP_0].rescale, -i);
  83.     Text->mipMaps[i].y = Text->mipMaps[MIPMAP_0].y >> i;
  84.     Text->mipMaps[i].x0 = Text->mipMaps[MIPMAP_0].x0 >> i;
  85.   }
  86.  
  87.   {
  88.     int j;
  89.     int r = 0, g = 0, b = 0;
  90.     struct rgb rgb;
  91.     unsigned char *textFlow = Text->mipMaps[MIPMAP_0].rawBody.data;
  92.  
  93.     for (j = Text->mipMaps[MIPMAP_0].rawBody.size; j > 0; j--) {
  94.       int k = (int)*textFlow++;
  95.  
  96.       r += cachedPalette[k].r;
  97.       g += cachedPalette[k].g;
  98.       b += cachedPalette[k].b;
  99.     }
  100.     rgb.r = r / Text->mipMaps[MIPMAP_0].rawBody.size;
  101.     rgb.g = g / Text->mipMaps[MIPMAP_0].rawBody.size;
  102.     rgb.b = b / Text->mipMaps[MIPMAP_0].rawBody.size;
  103.     Text->textureColor = (unsigned char)Match(&rgb, cachedPalette);
  104.   }
  105.  
  106.   if (!(Text->tiled = (void *)kmalloc((Text->mipMaps[MIPMAP_0].newBody.size + 1) * localDim.frameBPP)))
  107.     Error(failed_memory, (Text->mipMaps[MIPMAP_0].newBody.size + 1) * localDim.frameBPP, mip->name);
  108.  
  109.   Text->texChanged = TRUE;                    /* be very safe */
  110. }
  111.  
  112. static void GetExtents(__memBase, int face, struct texture *Text, int TInfo)
  113. {
  114.   float uv[32][2], *u, *v, umin, umax, vmin, vmax;
  115.   short int i, n = bspMem->shared.quake1.dfaces[face].numedges;
  116.   int *se = &bspMem->shared.quake1.dsurfedges[bspMem->shared.quake1.dfaces[face].firstedge + n];
  117.  
  118.   u = bspMem->shared.quake1.texinfo[TInfo].vecs[0];
  119.   v = bspMem->shared.quake1.texinfo[TInfo].vecs[1];
  120.  
  121.   for (i = n - 1; i >= 0; --i) {
  122.     int j = *--se;
  123.     float *loc;
  124.  
  125.     if (j < 0)
  126.       loc = bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[-j].v[1]].point;
  127.     else
  128.       loc = bspMem->shared.quake1.dvertexes[bspMem->shared.quake1.dedges[ j].v[0]].point;
  129.  
  130.     uv[i][0] = DotProduct(loc, u) + u[3];
  131.     uv[i][1] = DotProduct(loc, v) + v[3];
  132.   }
  133.   umin = umax = uv[0][0];
  134.   vmin = vmax = uv[0][1];
  135.   for (i = n - 1; i >= 0; --i) {
  136.     if (uv[i][0] < umin)
  137.       umin = uv[i][0];
  138.     else if (uv[i][0] > umax)
  139.       umax = uv[i][0];
  140.     if (uv[i][1] < vmin)
  141.       vmin = uv[i][1];
  142.     else if (uv[i][1] > vmax)
  143.       vmax = uv[i][1];
  144.   }
  145.  
  146.   Text->faceExtent.u0 = (int)(umin) & ~15;
  147.   Text->faceExtent.v0 = (int)(vmin) & ~15;
  148.   Text->faceExtent.u1 = (int)(ceil(scalw(umax, -4))) << 4;    /* / 16 */
  149.   Text->faceExtent.v1 = (int)(ceil(scalw(vmax, -4))) << 4;    /* / 16 */
  150.   Text->faceExtent.u10 = Text->faceExtent.u1 - Text->faceExtent.u0;
  151.   Text->faceExtent.v10 = Text->faceExtent.v1 - Text->faceExtent.v0;
  152.  
  153.   if ((bspMem->shared.quake1.dfaces[face].lightofs != -1) && (bspMem->shared.quake1.lightdatasize)) {
  154.     Text->lightdata = &bspMem->shared.quake1.dlightdata[bspMem->shared.quake1.dfaces[face].lightofs];
  155.  
  156.     Text->lightmap.width = ((Text->faceExtent.u10) >> 4) + 1;
  157.     Text->lightmap.height = ((Text->faceExtent.v10) >> 4) + 1;
  158.     Text->lightmap.size = Text->lightmap.width * Text->lightmap.height;
  159.     if (!(Text->lightmap.data = (unsigned char *)kmalloc((Text->lightmap.size + 1) * sizeof(int))))
  160.       Error(failed_memory, (Text->lightmap.size + 1) * sizeof(int), "lightmap");
  161.  
  162.     for (i = 0; i < MAXLIGHTMAPS; i++) {
  163.       short int lightStyle;
  164.  
  165.       lightStyle = (short int)bspMem->shared.quake1.dfaces[face].styles[i];
  166.  
  167.       if (lightStyle == 255)
  168.     break;
  169.       if (lightStyle > 11)
  170.     lightStyle = 0;
  171.  
  172.       Text->lightSString[i] = &lightstyleStrings[lightStyle][0];
  173.       Text->lightSLength[i] = lightstyleLengths[lightStyle];
  174.     }
  175.   }
  176.   else
  177.     Text->lightdata = 0;
  178.  
  179.   Text->texChanged = TRUE;                    /* be very safe */
  180. }
  181.  
  182. static void GetGradients(__memBase, int face, struct texture *Text, int TInfo)
  183. {
  184.   struct dplane_t *plane = Text->textGradient.plane = &bspMem->shared.quake1.dplanes[bspMem->shared.quake1.dfaces[face].planenum];
  185.   float dot, dot0, dot1;
  186.   vec3_t norm;
  187.   float *vec0 = bspMem->shared.quake1.texinfo[TInfo].vecs[0];
  188.   float *vec1 = bspMem->shared.quake1.texinfo[TInfo].vecs[1];
  189.  
  190.   CrossProduct(vec0, vec1, norm);
  191.  
  192.   dot = DotProduct(norm, plane->normal);
  193.  
  194.   if ((dot0 = -DotProduct(vec0, plane->normal) / dot))        /* for setup_uv_vector */
  195.     VectorMA(vec0, dot0, norm, Text->textGradient.uv0);
  196.   else
  197.     VectorCopy(vec0, Text->textGradient.uv0);
  198.  
  199.   if ((dot1 = -DotProduct(vec1, plane->normal) / dot))        /* for setup_uv_vector */
  200.     VectorMA(vec1, dot1, norm, Text->textGradient.uv1);
  201.   else
  202.     VectorCopy(vec1, Text->textGradient.uv1);
  203.  
  204.   VectorScale(norm, (plane->dist / dot), Text->textGradient.scaled);    /* for setup_origin_vector; */
  205.  
  206.   Text->textGradient.u -= vec0[3];
  207.   Text->textGradient.v -= vec1[3];
  208.   Text->texChanged = TRUE;                    /* be very safe */
  209. }
  210.  
  211. struct texture *CacheFace(__memBase, int face)
  212. {
  213.   struct texture *Text;
  214.   int TInfo = bspMem->shared.quake1.dfaces[face].texinfo;
  215.   int TMipMap = bspMem->shared.quake1.texinfo[TInfo].miptex;
  216.  
  217.   if (!(Text = (struct texture *)kmalloc(sizeof(struct texture))))
  218.     Error(failed_memory, sizeof(struct texture), "texture cache");
  219.  
  220.   GetExtents(bspMem, face, Text, TInfo);
  221.   GetMipMaps(bspMem, Text, TMipMap);
  222.   GetGradients(bspMem, face, Text, TInfo);
  223.   Text->texChanged = TRUE;                    /* be very safe */
  224.  
  225.   return Text;
  226. }
  227.